
import sys
import numpy
from params import Parameters
from util import design_window,design_filter_bank

# followed old version matlab
# it is just for reference. wil not be maintained.

# 1/32768
ONEOVERSHORTMAX = 3.0517578125e-5
segmentDuration = 1;
frameDuration = 0.025;
hopDuration = 0.010;
numBands = 40;
epsil = 1e-6;

class spectrogram:
    def __init__(self,** kwargs):
        self.params= Parameters()
        
        self.previousFrameSize = 0
        self.params.set_param(**kwargs)

    def set_param(self,**kwargs):    
        self.params.set_param(**kwargs)
               
    def setup(self,nSampleRate,nRow):            
        nChanged = 0
        if nSampleRate != self.params.SampleRate:
            self.params.set_frame_param(nSampleRate)          
            nChanged =  1        
            
            self.pFilterBank = design_filter_bank(self.params)
    
        
        if nChanged != 0 or nRow != self.previousFrameSize:        
            numHops = int((nRow-self.params.WindowLength)/self.params.HopLength) + 1;    
            win = design_window(self.params.WindowType,self.params.WindowLength);
            self.pWindow = numpy.repeat(win,numHops,axis=1);
         
            # Determine indices for reshaping
            overlap    = self.params.WindowLength - self.params.HopLength;
            self.ncol       = int((nRow-overlap)/(self.params.HopLength));
            #coloffsets = numpy.arange(ncol)*(self.params.HopLength);
            #self.pIdx  = numpy.arange(self.params.WindowLength).T+coloffsets;
            self.data0 = numpy.empty([self.params.WindowLength,self.ncol])
            self.previousFrameSize = nRow;
            self.spectrogram = numpy.empty([self.params.NumBands,self.ncol])
            #print(win[0:10,0] )       
            #print(self.pWindow[0:10,0] )   
            #print(self.params.WindowType)

                     	
    def calc(self,x,sample_rate):
        #  setup filter bank,...,etc if needed
        nRow =  x.shape[0]
        self.setup(sample_rate,nRow)
        # build array of  window
        for i in range(self.ncol):
            for j in range(self.params.WindowLength):        	
                z=x[i*self.params.HopLength+j]*ONEOVERSHORTMAX  
                self.data0[j,i]=z
        # .* pWindow
        data1 = self.data0*self.pWindow  	
        # fft
        data2 = numpy.fft.fft(data1,self.params.FFTLength,axis = 0)
        
        # abs
        AA = numpy.abs(data2)
        # apply filterBank
        for idx in range(self.ncol):
          self.spectrogram[:,idx]= numpy.dot( self.pFilterBank,AA[:,idx])
        #print(self.data0[0:10,0])
        #print(type(self.data0[0,0]))        
        #print(type(x[0]))
        #print(self.pWindow.shape)                  
        #print(self.data0.shape)        
        #sys.exit(0)
        #print(data1[0:10,0])        
        #print(self.pWindow[0:10,0])        	
        #sys.exit(0)        
        #print(data2.shape)
        #print(data2[0:10,0])
        #sys.exit(0)                
        #print(AA.shape)
        #print(AA[0:10,0])
        #sys.exit(0)        	        
        #print(self.spectrogram.shape)        
        #print(self.pFilterBank.shape)
        #print(self.spectrogram[0:10,0])
        #print(self.pFilterBank[0,0:20])        	
        #sys.exit(0)        	  
        return  self.spectrogram
       
if  __name__ == "__main__":
	  from util import default_params
	  params = default_params()
	  inst =  spectrogram()
	  inst.set_param(**params)
	  inst.setup(16000,16000)
	  print(inst.pWindow.shape)
	  print(inst.ncol)	  
